package com.sigmatrix.h5.service.impl;

import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.sigmatrix.h5.properties.WxSmallProgramProperties;
import com.sigmatrix.h5.service.WeChatSmallProgramService;
import com.sigmatrix.h5.utils.HttpClientUtils;
import com.sigmatrix.h5.web.args.SmallProgramTemplateMessage;
import com.sigmatrix.h5.web.mode.ErrorMessage;
import com.sigmatrix.h5.web.mode.SmallProgramTitle;
import com.sigmatrix.sc.rabbitmq.lang.RabbitSender;

/**
 * 
 *@ClassName: WeChatSmallProgramServiceImpl
 *@Description: 微信小程序
 *@author MH
 *@date 2017年12月25日 下午2:32:04
 */
@Service
public class WeChatSmallProgramServiceImpl implements WeChatSmallProgramService{
	
	Logger logger = Logger.getLogger(WeChatSmallProgramServiceImpl.class);
	private static String ACCESS_TOKEN = "";
	private final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token";
	private final String OPEN_ID_URL = "https://api.weixin.qq.com/sns/jscode2session";
	private final String SEND_TEMPLATE_MESSAGE_URL = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=";

	@Autowired
	private WxSmallProgramProperties property;
	@Autowired
	private RabbitSender sender;
	private Kryo kryo = new Kryo();
	@Override
	public String sendTemplateMessage(List<ErrorMessage> message,SmallProgramTemplateMessage sp) {
		//TODO 分布式部署时可能会遇到token被替换的问题，目前只有这一个地方用到小程序，没有必要再单独写一个项目维护小程序，所以每次请求都要刷新,等有时间也像isv那样做成定时
		refreshAccessToken();
		//发送消息
		HashMap<String,Object> map = new HashMap<String,Object>();
		map.put("touser", sp.getOpenId());
		map.put("template_id", property.getTemplateId());
		map.put("form_id", sp.getFormId());
		map.put("data", new SmallProgramTitle("处理完毕", "空", new Date()));
		map.put("page", sp.getPageUrl()+"?data="+JSONObject.toJSONString(message));
		String result = HttpClientUtils.postString(SEND_TEMPLATE_MESSAGE_URL+ACCESS_TOKEN, map);
		logger.info("发送模板消息返回结果："+result);
		return result;
	}
	
	/**
	 * 
	 *@Title: refreshAccessToken
	 *@Description:刷新access_token 
	 *@return void
	 *@author MH
	 *@date 2017年12月25日 下午6:00:10
	 */
	public void refreshAccessToken(){
		HashMap<String,Object> map = new HashMap<String,Object>();
		map.put("appid", property.getAppId());
		map.put("grant_type", property.getGrantType());
		map.put("secret", property.getSecret());
		String result = HttpClientUtils.getString(ACCESS_TOKEN_URL, map);
		ACCESS_TOKEN = JSONObject.parseObject(result).get("access_token")+"";
		logger.info("刷新微信小程序access_token:"+ACCESS_TOKEN);
	}

	@Override
	public String getOpenId(String jsCode) {
		HashMap<String,Object> map = new HashMap<String,Object>();
		map.put("appid", property.getAppId());
		map.put("grant_type", property.getGrantType());
		map.put("js_code", jsCode);
		map.put("secret", property.getSecret());
		String result = HttpClientUtils.getString(OPEN_ID_URL, map);
		logger.info("获取微信小程序openid:"+result);
		return JSONObject.parseObject(result).get("openid")+"";
	}
	public static class SmallMessage implements Serializable{
		private static final long serialVersionUID = -2188203499086314246L;
		private List<ErrorMessage> data;
		private SmallProgramTemplateMessage sp;
		public List<ErrorMessage> getData() {
			return data;
		}
		public SmallMessage() {
			super();
		}
		public void setData(List<ErrorMessage> data) {
			this.data = data;
		}
		public SmallMessage(List<ErrorMessage> data, SmallProgramTemplateMessage sp) {
			super();
			this.data = data;
			this.sp = sp;
		}
		public SmallProgramTemplateMessage getSp() {
			return sp;
		}
		public void setSp(SmallProgramTemplateMessage sp) {
			this.sp = sp;
		}
	}
	@Override
	public void submitTask(List<ErrorMessage> message, SmallProgramTemplateMessage sp) {
		//sendTemplateMessage(message, sp);
		sender.send(2, new SmallMessage(message, sp));
	}
	
	@RabbitListener(queues="${rabbit.bindings[2].queue}")
	public void dealWithMessage(org.springframework.amqp.core.Message message){
		logger.info("发送小程序收到一条消息"+message);
		Input input = new Input(message.getBody());
		SmallMessage msg = kryo.readObject(input, SmallMessage.class);
		input.close();
		sendTemplateMessage(msg.getData(), msg.getSp());
	}
}
